﻿using System;
using System.Security.Cryptography;
using System.Text;
using System.Web.Security;

namespace CSharpHelpers.Encrypts
{
    public class EncryptHelper
    {
        //对输入密码进行MD5加密
        //pwdMD5 = FormsAuthentication.HashPasswordForStoringInConfigFile(txtConfirmPwd.Text, "MD5");

        /// <summary>
        /// MD5加密算法
        /// </summary>
        /// <param name="encypStr"></param>
        /// <returns></returns>
        public static string Md5Encyp(string encypStr)
        {
            string retStr;
            MD5CryptoServiceProvider m5 = new MD5CryptoServiceProvider();
            byte[] inputBye;
            byte[] outputBye;
            inputBye = Encoding.ASCII.GetBytes(encypStr);
            outputBye = m5.ComputeHash(inputBye);
            retStr = Convert.ToBase64String(outputBye);
            return (retStr);
        }

        public enum EncryptType
        {
            SHA1,
            MD5
        }

        public static string EncryptPassword(string PasswordString, EncryptType encryptType)
        {
            string encryptPassword = null;
            if (encryptType == EncryptType.SHA1)
                encryptPassword = FormsAuthentication.HashPasswordForStoringInConfigFile(PasswordString, "SHA1");
            else if (encryptType == EncryptType.MD5)
                encryptPassword = FormsAuthentication.HashPasswordForStoringInConfigFile(PasswordString, "MD5");

            return encryptPassword;
        }

        public static readonly byte[] INI_KEY = new byte[] { 35, 36, 37, 38, 39, 65, 32, 35 };//加密密码，如果在文件头部找到这8个字符表示已加密，解密则去掉

        /// <summary>
        /// 加密方法,
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public static byte[] Encrypt(byte[] buffer)
        {
            byte[] newbuffer = new byte[buffer.Length + 8];
            for (int i = 0; i < 8; i++)
            {
                newbuffer[i] = INI_KEY[i];
            }

            for (int i = 0; i < buffer.Length; i++)
            {
                newbuffer[i + 8] = (byte)(buffer[i] + 10);
            }

            return newbuffer;
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public static byte[] Decrypt(byte[] buffer)
        {
            byte[] newbuffer = new byte[buffer.Length - 8];
            for (int i = 0; i < buffer.Length - 8; i++)
            {
                newbuffer[i] = (byte)(buffer[i + 8] - 10);
            }

            return newbuffer;
        }

        /// <summary>
        /// 判断是否加密
        /// 是就返回true
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public static bool IsEncrypted(byte[] buffer)
        {
            for (int i = 0; i < 8; i++)
            {
                if (buffer[i] != INI_KEY[i])
                {
                    return false;
                }
            }

            return true;
        }

        //////////////////////////////////////////CRC相关方法////////////////////////////////

        //获取CRC码
        public static int CRC(byte[] buffer, int len, int crcval)
        {
            int c, q;
            for (int Index = 0; Index < len; Index++)
            {
                c = (int)buffer[Index];
                q = (crcval ^ c) & 15;
                crcval = (crcval >> 4) ^ (q * 4225);
                q = (crcval ^ (c >> 4)) & 15;
                crcval = (crcval >> 4) ^ (q * 4225);
            }

            return crcval;
        }

        /// <summary>
        /// 生成CRC的低位和高位码
        /// </summary>
        /// <param name="src"></param>
        /// <param name="highbyte"></param>
        /// <param name="lowerbyte"></param>
        public static void breakShort(int src, out char highbyte, out char lowerbyte)
        {
            lowerbyte = (char)(src & 0xff);
            highbyte = (char)(src >> 8);
        }

        /// <summary>
        /// 校验CRC码是否正确
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static bool IsCRC(byte[] buffer)
        {
            char lowerbyte, highbyte, thisLowerbyte, thisHighbyte;
            int crcval;
            thisLowerbyte = Convert.ToChar(buffer[buffer.Length - 2]);
            thisHighbyte = Convert.ToChar(buffer[buffer.Length - 1]);
            crcval = CRC(buffer, buffer.Length - 2, 0);
            breakShort(crcval, out highbyte, out lowerbyte);

            if (highbyte == thisHighbyte && lowerbyte == thisLowerbyte)
                return true;
            else
                return false;
        }
        /// <summary>
        /// 为加密后的ini追加CRC
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public static byte[] AddCRC(byte[] buffer, char highbyte, char lowerbyte)
        {
            byte[] newbuffer = new byte[buffer.Length + 2];
            for (int i = 0; i < buffer.Length; i++)
            {
                newbuffer[i] = buffer[i];
            }
            newbuffer[newbuffer.Length - 2] = Convert.ToByte(lowerbyte);
            newbuffer[newbuffer.Length - 1] = Convert.ToByte(highbyte);
            return newbuffer;
        }
        /// <summary>
        /// 去掉CRC
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public static byte[] DelCRC(byte[] buffer)
        {
            byte[] newbuffer = new byte[buffer.Length - 2];
            for (int i = 0; i < buffer.Length - 2; i++)
            {
                newbuffer[i] = buffer[i];
            }
            return newbuffer;
        }
    }
}
